#!/usr/bin/python3

# Copyright (c) 2020-2021 Fpemud <fpemud@sina.com>
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.


import os
import enum


MOUNT_DIR = os.path.join("/run/user/%d/datadisks" % (os.getuid()))


class PartitionTableType(enum.Enum):

    # using parted partition type name as enum value
    GPT = "gpt"
    MBR = "msdos"

    def __str__(self):
        return _partition_table_type_info[self][0]


class FileSystemType(enum.Enum):

    # using linux fstype as enum value
    EXFAT = "exfat"
    FAT = "vfat"
    NTFS = "ntfs"

    def __str__(self):
        return _fs_type_info[self][0]


class CompatibleOs(enum.Enum):

    LINUX = enum.auto()

    WINDOWS_9X = enum.auto()
    WINDOWS_XP = enum.auto()
    WINDOWS_VISTA = enum.auto()
    WINDOWS_7 = enum.auto()
    WINDOWS_8 = enum.auto()
    WINDOWS_10 = enum.auto()
    WINDOWS_11 = enum.auto()

    WINDOWS_SERVER_2008 = enum.auto()
    WINDOWS_SERVER_2012 = enum.auto()
    WINDOWS_SERVER_2016 = enum.auto()
    WINDOWS_SERVER_2019 = enum.auto()

    def __str__(self):
        return _compat_os_info[self][0]

    @classmethod
    def get_default_compatible_os_list(cls):
        return [
            cls.LINUX,
            cls.WINDOWS_XP,
            cls.WINDOWS_7,
            cls.WINDOWS_10,
            cls.WINDOWS_11,
        ]

    @staticmethod
    def is_partition_table_type_valid_for_compatible_os_list(partition_table_type, compatible_os_list):
        assert len(compatible_os_list) > 0
        return all([partition_table_type in _compat_os_info[x][1] for x in compatible_os_list])

    @staticmethod
    def get_partition_table_type_for_compatible_os_list(compatible_os_list):
        for p in PartitionTableType:
            bFound = True
            for cos in compatible_os_list:
                if p not in _compat_os_info[cos][1]:
                    bFound = False
                    break
            if bFound:
                return p
        return None

    @staticmethod
    def is_file_system_type_valid_for_compatible_os_list(file_system_type, compatible_os_list):
        assert len(compatible_os_list) > 0
        return all([file_system_type in _compat_os_info[x][2] for x in compatible_os_list])

    @staticmethod
    def get_file_system_type_for_compatible_os_list(compatible_os_list):
        for fs in FileSystemType:
            bFound = True
            for cos in compatible_os_list:
                if fs not in _compat_os_info[cos][2]:
                    bFound = False
                    break
            if bFound:
                return fs
        return None


_partition_table_type_info = {
    PartitionTableType.GPT: (
        "GPT",                  # show name
    ),
    PartitionTableType.MBR: (
        "MBR",
    ),
}


_fs_type_info = {
    FileSystemType.FAT: (
        "FAT",                  # show name
    ),
    FileSystemType.EXFAT: (
        "exFAT",
    ),
}


_compat_os_info = {
    CompatibleOs.LINUX: (
        "linux",                                                            # show name
        [PartitionTableType.GPT, PartitionTableType.MBR],                   # partition table type, more preferable item lists first
        [FileSystemType.EXFAT, FileSystemType.FAT, FileSystem.NTFS],        # filesystem, more preferable item lists first
    ),
    CompatibleOs.WINDOWS_9X: (
        "windows-9x",
        [PartitionTableType.MBR],
        [FileSystemType.FAT],
    ),
    CompatibleOs.WINDOWS_XP: (
        "windows-xp",
        [PartitionTableType.MBR],
        [FileSystemType.FAT, FileSystem.NTFS],
    ),
    CompatibleOs.WINDOWS_VISTA: (
        "windows-vista",
        [PartitionTableType.MBR],
        [FileSystemType.FAT, FileSystem.NTFS],
    ),
    CompatibleOs.WINDOWS_7: (
        "windows-7",
        [PartitionTableType.GPT, PartitionTableType.MBR],
        [FileSystemType.EXFAT, FileSystemType.FAT, FileSystem.NTFS],
    ),
    CompatibleOs.WINDOWS_8: (
        "windows-8",
        [PartitionTableType.GPT, PartitionTableType.MBR],
        [FileSystemType.EXFAT, FileSystemType.FAT, FileSystem.NTFS],
    ),
    CompatibleOs.WINDOWS_10: (
        "windows-10",
        [PartitionTableType.GPT, PartitionTableType.MBR],
        [FileSystemType.EXFAT, FileSystemType.FAT, FileSystem.NTFS],
    ),
    CompatibleOs.WINDOWS_11: (
        "windows-11",
        [PartitionTableType.GPT, PartitionTableType.MBR],
        [FileSystemType.EXFAT, FileSystemType.FAT, FileSystem.NTFS],
    ),
    CompatibleOs.WINDOWS_SERVER_2008: (
        "windows-server-2008",
        [PartitionTableType.GPT, PartitionTableType.MBR],
        [FileSystemType.EXFAT, FileSystemType.FAT, FileSystem.NTFS],
    ),
    CompatibleOs.WINDOWS_SERVER_2012: (
        "windows-server-2012",
        [PartitionTableType.GPT, PartitionTableType.MBR],
        [FileSystemType.EXFAT, FileSystemType.FAT, FileSystem.NTFS],
    ),
    CompatibleOs.WINDOWS_SERVER_2016: (
        "windows-server-2016",
        [PartitionTableType.GPT, PartitionTableType.MBR],
        [FileSystemType.EXFAT, FileSystemType.FAT, FileSystem.NTFS],
    ),
    CompatibleOs.WINDOWS_SERVER_2019: (
        "windows-server-2019",
        [PartitionTableType.GPT, PartitionTableType.MBR],
        [FileSystemType.EXFAT, FileSystemType.FAT, FileSystem.NTFS],
    ),
}
